package servlets;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import service.ErrorService;
import service.ValidateInput;
import dao.ParticipantListDAO;
import dao.PlacementListDAO;
import dao.RoleDAO;
import dao.TeamDAO;
import dao.TeamInfoDAO;
import dao.TournamentDAO;
import daoimpl.ParticipantListDAOImpl;
import daoimpl.PlacementListDAOImpl;
import daoimpl.RoleDAOImpl;
import daoimpl.TeamDAOImpl;
import daoimpl.TeamInfoDAOImpl;
import daoimpl.TournamentDAOImpl;
import dto.ParticipantListDTO;
import dto.PlacementListDTO;
import dto.RoleDTO;
import dto.TeamDTO;
import dto.TeamInfoDTO;
import dto.TournamentDTO;
import dto.UserDTO;
import exceptions.DALException;

/**
 * Servlet implementation class TournamentSelector
 */
@WebServlet("/TournamentSelector")
public class TournamentSelector extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private int tId;

	private UserDTO udto;
	private TournamentDTO tourDTO;
	private TeamDAO teamDAO;
	private TeamInfoDAO teamIDAO;
	private RoleDAO roleDAO;
	private TournamentDAO tourDAO;
	private ParticipantListDAO pDAO;
	private List<TeamDTO> teamList;
	private List<ParticipantListDTO> participantList;
	private List<PlacementListDTO> placementList;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public TournamentSelector() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String id = request.getParameter("id");
		if (id != null) {
			tId = Integer.parseInt(request.getParameter("id"));
		}

		UserDTO uDTO = (UserDTO) request.getSession().getAttribute("userObject");

		try {

			TournamentDAO tDAO = new TournamentDAOImpl();
			ParticipantListDAO participantDAO = new ParticipantListDAOImpl();
			TeamInfoDAO teamInfoDAO = new TeamInfoDAOImpl();
			PlacementListDAO plDAO = new PlacementListDAOImpl();
			
			TournamentDTO tDTO = tDAO.getTournament(tId);
			

			Integer teamCount = participantDAO.getParticipantCount(tId);
			participantList = participantDAO.getTeamList(tId);

			if (tDTO.getStatus() == 2) { // if the tournament is finished - get the placementlist
				placementList = plDAO.getPlacementList(tId);
				
				String placementListofTourn = "";
				
				for (PlacementListDTO placement : placementList) {
					TeamInfoDTO teamInfo = teamInfoDAO.getTeam(placement.getTeamId());
					if (placement.getPlacement() == 0) {
						placementListofTourn += "<li>" + "(result to be entered)" + "   " + teamInfo.getTeamName() + "</li>";
					}
					else {
					placementListofTourn += "<li>" + placement.getPlacement() + "   " + teamInfo.getTeamName() + "</li>";
					}
				}
				request.setAttribute("placementList", placementListofTourn);
			}
			
			String listParticipantsInTourn = "";

			for (ParticipantListDTO participant : participantList) {
				TeamInfoDTO teamInfo = teamInfoDAO.getTeam(participant.getTeamId());
				listParticipantsInTourn += "<li>" + teamInfo.getTeamName() + "</li>";
			}

			System.out.println(listParticipantsInTourn);


			request.setAttribute("teamList", listParticipantsInTourn);
			request.setAttribute("Tournament", tDTO);
			request.setAttribute("teamCount", teamCount);
			
			tDAO.closeConnection();
			participantDAO.closeConnection();
			teamInfoDAO.closeConnection();
			plDAO.closeConnection();

		} catch (DALException e) {
			String error = e.getMessage();
			System.out.println(error);
			request.setAttribute("error", error);
			this.getServletContext().getRequestDispatcher("/errorpage.jsp").forward(request, response);
			return;
		}

		try {
			roleDAO = new RoleDAOImpl();
			RoleDTO rDTO = roleDAO.getRole(uDTO.getId(), tId);

			// user is organizer
			if ((rDTO.getRole()) == 1) {
				request.setAttribute("organisor", true);
				this.getServletContext().getRequestDispatcher("/WEB-INF/user/EditTournament.jsp").forward(request, response);
			}
			// user is participant
			else {
				request.setAttribute("participant", true);
				this.getServletContext().getRequestDispatcher("/WEB-INF/user/ViewTournament.jsp").forward(request, response);
			}
			
			roleDAO.closeConnection();
			
		}
		// user is neither a participant nor a organizer so he is forwarded to
		// view tournament
		catch (DALException e) {
			this.getServletContext().getRequestDispatcher("/WEB-INF/user/ViewTournament.jsp").forward(request, response);
		}

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		int tId = Integer.parseInt(request.getParameter("id"));
		udto = (UserDTO) request.getSession().getAttribute("userObject");

		try {
			TournamentDAO tDAO = new TournamentDAOImpl();
			TournamentDTO tDTO = tDAO.getTournament(tId);
			request.setAttribute("Tournament", tDTO);

			if (tDTO.getStatus() == 0) {

				if (request.getParameter("joinButton") != null) {
					System.out.println("Joining Tour");
					joinTour(tId, request, response);
				} else if (request.getParameter("leaveButton") != null) {
					System.out.println("Leaving Tour");
					leaveTour(tId, request, response);
				}
			}
			else {
				System.out.println("Tournament in progress");
				System.out.println("Missing logic");
				// Tournament in progress
				//				ValidateInput validate = new ValidateInput();
				//				ErrorService error = validate.createError();
				//				error.setError("<div class=\"alert alert-danger\">Cant join or leave a tournament in progress</div>");
				//				request.setAttribute("error", error);
			}

		} catch (DALException e) {
			String error = e.getMessage();
			System.out.println(error);
			request.setAttribute("error", error);
			this.getServletContext().getRequestDispatcher("/errorpage.jsp").forward(request, response);
			return;
		}

		//		response.sendRedirect(request.getContextPath()+ "/Navigation?page=Main");
		ErrorService error = (ErrorService) request.getAttribute("error");
		request.setAttribute("error", error);

		doGet(request, response);
	}

	private void leaveTour(int tournamentId, HttpServletRequest request,
			HttpServletResponse response) {

		System.out.println("Leave pressed");

		ValidateInput validate = new ValidateInput();
		ErrorService error = validate.createError();
		String errorMessage = "";

		try {

			teamDAO = new TeamDAOImpl();
			teamIDAO = new TeamInfoDAOImpl();
			roleDAO = new RoleDAOImpl();
			teamIDAO.getTeamList();
			teamList = teamDAO.getTeamPlayerList();
			tourDAO = new TournamentDAOImpl();
			tourDTO = tourDAO.getTournament(tournamentId);
			int teamID = 0;

			List<TeamInfoDTO> leaderList = listOfTeamsLeadByUser(udto);

			if (leaderList != null) {
				if (checkSport(leaderList, tourDTO.getSport()) == true) {

					for(TeamDTO playersTeam: teamDAO.getTeamList(udto.getId())){
						if(teamIDAO.getTeam(playersTeam.getTeamId()).getSport()
								.equals(tourDTO.getSport())){
							teamID = playersTeam.getTeamId();
						}
					}

					if(teamID!=0){
						pDAO = new ParticipantListDAOImpl();
						pDAO.disableParticipant(new ParticipantListDTO(teamID, tId));
						pDAO.closeConnection();
					}
					

					for (TeamDTO teamDTO : teamList) {
						if (teamDTO.getTeamId() == teamID&&teamIDAO.getTeam(teamDTO.getTeamId()).getSport()
								.equals(tourDTO.getSport())) {
							roleDAO.disableRole(new RoleDTO(
									teamDTO.getUserId(), tournamentId, 2));
							System.out.println(teamDTO.getUserId() + " Joined");
						}
					}
				} else {
					errorMessage = "<div class=\"alert alert-danger\"> Bruger ikke team leader for den korrekte sport </div>";
					// user is not a teamleader for a team of the correct sport
				}
			} else {
				// User is not a teamleader
				errorMessage = "<div class=\"alert alert-danger\"> Bruger er ikke team leader for et hold </div>";
			}
			
			teamDAO.closeConnection();
			teamIDAO.closeConnection();
			roleDAO.closeConnection();
			tourDAO.closeConnection();

		} catch (DALException e) {
			error.setError(e.getMessage());
			request.setAttribute("error", error);
		}

		error.setError(errorMessage);
		request.setAttribute("error", error);
	}

	public void joinTour(int tournamentId, HttpServletRequest request,
			HttpServletResponse response) {

		ValidateInput validate = new ValidateInput();
		ErrorService error = validate.createError();
		String errorMessage = "";

		try {

			System.out.println("Join pressed");
			teamDAO = new TeamDAOImpl();
			teamIDAO = new TeamInfoDAOImpl();
			roleDAO = new RoleDAOImpl();
			teamIDAO.getTeamList();
			teamList = teamDAO.getTeamPlayerList();
			tourDAO = new TournamentDAOImpl();
			pDAO = new ParticipantListDAOImpl();
			tourDTO = tourDAO.getTournament(tournamentId);
			int teamID = 0;

			List<TeamInfoDTO> leaderList = listOfTeamsLeadByUser(udto);

			if (leaderList != null) {
				if (checkSport(leaderList, tourDTO.getSport()) == true) {

					for(TeamDTO playersTeam: teamDAO.getTeamList(udto.getId())){
						if(teamIDAO.getTeam(playersTeam.getTeamId()).getSport()
								.equals(tourDTO.getSport())){
							teamID = playersTeam.getTeamId();
						}
					}
					
					if(teamID!=0){
						pDAO.createParticipant(new ParticipantListDTO(teamID, tId));
					}

					for (TeamDTO teamDTO : teamList) {
						if (teamDTO.getTeamId() == teamID&&teamIDAO.getTeam(teamDTO.getTeamId()).getSport().equals(tourDTO.getSport())) {
							roleDAO.createRole(new RoleDTO(teamDTO.getUserId(), tournamentId, 2));
							System.out.println(teamDTO.getUserId() + " Joined");
						}
					}
				} else {
					errorMessage = "<div class=\"alert alert-danger\"> Bruger ikke team leader for den korrekte sport </div>";
					// user is not a teamleader for a team of the correct sport
				}
			} else {
				// User is not a teamleader
				errorMessage = "<div class=\"alert alert-danger\"> Bruger er ikke team leader for et hold </div>";
			}

			teamDAO.closeConnection();
			teamIDAO.closeConnection();
			roleDAO.closeConnection();
			tourDAO.closeConnection();
			pDAO.closeConnection();
			
		} catch (DALException e) {
			error.setError(e.getMessage());
			request.setAttribute("error", error);
		}

		error.setError(errorMessage);
		request.setAttribute("error", error);

	}

	private List<TeamInfoDTO> listOfTeamsLeadByUser(UserDTO user) {
		int userId = user.getId();

		List<TeamInfoDTO> teamlist;
		List<TeamInfoDTO> leaderlist = new ArrayList<TeamInfoDTO>();

		try {
			teamlist = teamIDAO.getTeamList();

			for (int i = 0; i < teamlist.size(); i++) {
				if (teamlist.get(i).getUserId() == userId) {
					leaderlist.add(teamlist.get(i));
				}
			}

		} catch (DALException e) {
			e.printStackTrace();
		}
		return leaderlist;
	}

	private boolean checkSport(List<TeamInfoDTO> list, String sport) {
		boolean result = false;
		for (TeamInfoDTO teamInfo : list) {
			if (teamInfo.getSport().equals(sport)) {
				System.out.println("True sport");
				result = true;
			}
		}
		return result;
	}

}
